const canvas1 = document.createElement('canvas')
const canvas2 = document.createElement('canvas')
const ctx1 = canvas1.getContext('2d')
const ctx2 = canvas2.getContext('2d')

function initCanvas(canvas) {
  canvas.width = 400
  canvas.height = 400
  document.body.appendChild(canvas)
}

initCanvas(canvas1)
initCanvas(canvas2)

const cell = 20
let grid = {}

function initGrid() {
  for (let i = 0; i < canvas1.width / cell; i++) {
    for (let j = 0; j < canvas1.height / cell; j++) {
      grid[`${i * cell}-${j * cell}`] = 0
    }
  }
}
initGrid()

// 绘制棋盘
ctx1.save()
ctx1.strokeStyle = '#ccc'
for (let i = 0; i < canvas1.width / cell; i++) {
  ctx1.beginPath()
  ctx1.moveTo(i * cell, 0)
  ctx1.lineTo(i * cell, canvas1.width)
  ctx1.stroke()
  ctx1.beginPath()
  ctx1.moveTo(0, i * cell)
  ctx1.lineTo(canvas1.width, i * cell)
  ctx1.stroke()
}
ctx1.restore()

// 蛇头，蛇身（每一部分），食物
class Rect {
  constructor(x, y, color, type) {
    this.x = x
    this.y = y
    this.color = color
    this.oldX = x
    this.oldY = y
    this.w = cell
    this.h = cell
    this.type = type
  }
  draw() {
    ctx2.clearRect(this.oldX, this.oldY, this.w, this.h)
    if (!this.type) {
      grid[`${this.oldX}-${this.oldY}`] = 0
      grid[`${this.x}-${this.y}`] = 1
    }
    this.oldX = this.x
    this.oldY = this.y
    ctx2.save()
    ctx2.beginPath()
    ctx2.fillStyle = this.color
    ctx2.fillRect(this.x, this.y, this.w, this.h)
    ctx2.stroke()
  }
}

let isFirst
/**
 * @dir ArrowRight ArrowLeft ArrowUp ArrowDown
 */
class Snake {
  constructor(x, y, dir = 'ArrowRight') {
    this.x = x * cell
    this.y = y * cell
    this.dir = dir
    this.head = new Rect(this.x, this.y, '#f00')
    this.body = []
    this.timer = null
    this.score = 0
  }
  draw() {
    // 绘制蛇
    this.head.draw()
    if (this.body.length > 0) {
      this.body[0].draw()
    }
  }
  move() {
    switch (this.dir) {
      case 'ArrowRight':
        this.head.x += cell
        break
      case 'ArrowLeft':
        this.head.x -= cell
        break
      case 'ArrowUp':
        this.head.y -= cell
        break
      case 'ArrowDown':
        this.head.y += cell
        break
    }
    // 是否到达临界点
    if (this.isOver()) {
      // alert('结束')
      clearTimeout(this.timer)
      return
    }
    if (this.isEat()) {
      this.score += 10
      const rect = new Rect(this.head.oldX, this.head.oldY, '#0f0')
      this.body.unshift(rect)
      randomFood()
    } else {
      if (this.body.length > 0) {
        const last = this.body.pop()
        last.x = this.head.oldX
        last.y = this.head.oldY
        this.body.unshift(last)
      }
    }
    this.draw()
    isFirst = setTimeout(() => {
      console.log(1)
      this.move()
    }, 200 - 100)
  }
  isOver() {
    return (
      this.head.x < 0 ||
      this.head.y < 0 ||
      this.head.x >= canvas2.width ||
      this.head.y >= canvas2.height ||
      grid[`${this.head.x}-${this.head.y}`]
    )
  }
  isEat() {
    return this.head.x == food.x && this.head.y == food.y
  }
}
let food
// 随机生成食物
function randomFood() {
  // while (true) {
  const x = Math.floor((Math.random() * canvas2.width) / cell) * cell
  const y = Math.floor((Math.random() * canvas2.height) / cell) * cell
  if (grid[`${x}-${y}`]) {
    return
  }
  food = new Rect(x, y, '#00f', 1)
  food.draw()
  // break
  // }
}
randomFood()

canvas2.onclick = function () {
  clearTimeout(isFirst)
  ctx2.clearRect(0, 0, canvas2.width, canvas2.height)
  const snake = new Snake(1, 1)
  snake.draw()
  snake.move()
  randomFood()
  grid = {}
  initGrid()
  document.onkeydown = function (e) {
    if (
      e.code === 'ArrowRight' ||
      e.code === 'ArrowLeft' ||
      e.code === 'ArrowUp' ||
      e.code === 'ArrowDown'
    ) {
      if (
        (snake.dir === 'ArrowRight' && e.code === 'ArrowLeft') ||
        (snake.dir === 'ArrowLeft' && e.code === 'ArrowRight') ||
        (snake.dir === 'ArrowUp' && e.code === 'ArrowDown') ||
        (snake.dir === 'ArrowDown' && e.code === 'ArrowUp')
      ) {
        return
      }
      snake.dir = e.code
    }
  }
}
